#include "AVRMemory.h"
#include "../../../bit/bit.h"


void setEEPromAddress(unsigned long address)
{
	unsigned char upper = (unsigned char) ((address & 0xFF00)>>8);
	unsigned char lower = (unsigned char) (address & 0x00FF);
	lower = ((lower & 0x0300));
	EEARH = upper;
	EEARL = lower;
}

unsigned long getEEPromAddress()
{
	unsigned long temp = 0x0000;
	temp = EEARH;
	temp = temp << 8;
	temp = temp | EEARL;
	return temp;
}

unsigned char getEEPromData()
{
	unsigned char data = EEDR;
	return data;
}

void setEEPromData(unsigned char data)
{
	EEDR = data;
}


void setInterruptEEProm(unsigned char flag)
{
	EECR = SetBit(EECR, EERIE, flag);
}


void setMasterWriteEEProm(unsigned char flag)
{
	EECR = SetBit(EECR, EEMWE, flag);
}

void setWriteEnableEEProm(unsigned char flag)
{
	EECR = SetBit(EECR, EEWE, flag);
}

void setReadEnableEEProm(unsigned char flag)
{
	EECR = SetBit(EECR, EERE, flag);
}


enum EEPROM_HardwareState { ReadEEPROM_Hardware, WriteEEPROM_Hardware, DoNothingHardware};
volatile unsigned char EEPROM_Operation = DoNothingHardware;
volatile unsigned char PreviousOperation = DoNothingHardware;

volatile unsigned char EEPROMReadFlag = 0;
volatile unsigned char EEPROMWriteFlag = 0;

volatile unsigned long EEPROM_WriteADDR = 0;
volatile unsigned long EEPROM_ReadADDR = 0;

volatile unsigned char EEPROM_WriteData = 0;
volatile unsigned char EEPROM_ReadData = 0;
 
//determine if you should read write or do nothing

//example ISR
ISR(EE_RDY_vect)
{
	switch(PreviousOperation)
	{
		case ReadEEPROM_Hardware:
			//set flag that is finished reading
			//need to grab the new data.
			EEPROM_ReadData = getEEPROMData();
			EEPROMReadFlag = 1;
			break;
		case WriteEEPROM_Hardware:
			EEPROMWriteFlag = 1;

			break;
		case DoNothingEEPROM_Hardware:
			//no flag needs to be set.
			break;
		default:
			PreviousOperation = DoNothingHardware;
			break;
	}
	PreviousOperation = EEPROM_Operation; //set the previous operation..

	switch(EEPROM_Operation)
	{
		case ReadEEPROM_Hardware:
			//set up for reading new data
			setEEPromAddress(EEPROM_ReadADDR); 
			//the data is now invalid until
			//this finishes reading.
			setReadEnableEEProm(1); //sets for reading now.
			
			EEPROM_Operation = DoNothingHardware;
			break;
		case WriteEEPROM_Hardware:
			setEEPromAddress(EEPROM_WriteADDR);
			setEEPromData(EEPROM_WriteData);
			//now set master write now.
			setMasterWriteEEProm(1);
			//start the write now
			setWriteEnableEEProm(1);
			EEPROM_Operation = DoNothingHardware;
			break;
		case DoNothingEEPROM_Hardware:
			EEPROM_Operation = DoNothingHardware;
			break;
		default:
			EEPROM_Operation = DoNothingHardware;
			break;
	}	
}
